<!--
 * @Description  : 上传组件
 * @Autor        : 杜康
 * @Date         : 2023-04-21 14:36:51 +0800
 * @LastEditors  : 杜康
 * @LastEditTime : 2023-05-09 18:22:04 +0800
-->
<template>
  <div class="myupload">
    <el-upload
      drag
      :auto-upload="false"
      action="ddd"
      :file-list="fileList"
      :show-file-list="showFile"
      :on-change="handleChange"
      :on-remove="handleRemove"
      :accept="accept"
    >
      <div class="myupload-icon">
        <img v-for="item in 3" :key="item" :src="iconPath" alt="图片加载失败" />
      </div>
      <div class="el-upload__text">
        <em>点击上传</em> / 拖拽到此区域<br />
        <span v-text="desc"></span>
      </div>
    </el-upload>
    <el-progress
      v-if="progressFlag"
      :percentage="loadProgress"
      :stroke-width="4"
    ></el-progress>
  </div>
</template>

<script>
import wordImg from "@/assets/images/Word.svg";
import excleImg from "@/assets/images/Excel.svg";
// 此处调用真实上传文件接口
import { commonUpload } from "@/api/vm/system.js";
import { handlerReportMsg, firstLetterCap } from "@/utils/utils.js";
const iconPath = {
  word: wordImg,
  excel: excleImg,
};
export default {
  name: "MyUpload",
  props: {
    accept: {
      type: String,
      default: ".docx",
    },
    icon: {
      type: String,
      default: "word",
    },
    showFile: {
      type: Boolean,
      default: true,
    },
    desc: {
      type: String,
      default: "只能上传 Word 文件",
    },
  },
  data() {
    return {
      iconPath: iconPath[this.icon] || wordImg,
      fileList: [],
      progressFlag: false,
      loadProgress: 0,
    };
  },
  computed: {},
  methods: {
    firstLetterCap,
    /**
     * @description: 文件状态改变时的钩子，添加文件、上传成功和上传失败时都会被调用
     * @param {*} file
     * @param {*} fileList
     * @return {*}
     * @author: 杜康
     * @Date: 2023-04-21 16:02:06 +0800
     */
    async handleChange(file, fileList) {
      // 只展示最后一次上传文件
      if (fileList.length > 0) {
        this.fileList = [fileList[fileList.length - 1]];
      }
      const { name, size, raw } = file;
      // 允许最大上传文件为1GB
      const MAX_SIZE = 1000 * 1024 * 1024;
      if (MAX_SIZE <= size) {
        this.handleRemove();
        handlerReportMsg("", "只允许上传1GB以内的文件");
        return;
      }
      // 校验名称 只允许中文、英文、数字、下划线、横杠、点号
      // eslint-disable-next-line no-useless-escape
      const namePattern = /^[a-zA-Z0-9_\.\-\u4e00-\u9fa5]{1,100}$/g;
      if (!namePattern.test(name)) {
        handlerReportMsg(
          "",
          "文件名称不合法，只允许中文、英文、数字、下划线、横杠、点号"
        );
        return;
      }
      const params = new FormData();
      params.append("file", raw);
      const result = await commonUpload(params, {
        onUploadProgress: (node) => {
          const { total, loaded } = node;
          const tempProgress = loaded / total; // 上传进度
          this.progressFlag = true;
          this.loadProgress = parseInt(tempProgress * 100);
          if (tempProgress == 1) {
            this.progressFlag = false;
          }
        },
      });
      const { code, message, data } = result;
      if (Number(code) === 200) {
        this.$emit("fileInfo", data);
      } else {
        this.fileList = [];
        this.$emit("fileInfo", []);
        // handlerReportMsg(code, message);
      }
    },
    /**
     * @description: 文件列表移除文件时的钩子
     * @return {*}
     * @author: 杜康
     * @Date: 2023-04-21 16:11:12 +0800
     */
    handleRemove(file, fileList) {
      this.$emit("fileInfo", []);
    },
  },
};
</script>

<style lang="scss" scoped>
.myupload {
  position: relative;
  width: 100%;
  height: 100%;
  &-icon {
    height: 56px;
    margin: 24px 0 20px 0;
    img {
      &:nth-child(1) {
        margin-right: 14px;
      }
      &:nth-child(3) {
        margin-left: 14px;
        position: sticky;
        z-index: 10;
      }
      &:nth-child(2) {
        position: absolute;
        bottom: 96px;
        left: 44.2%;
      }
    }
  }
  ::v-deep {
    .el-upload {
      width: 100%;
      .el-upload-dragger {
        width: 100%;
        .el-upload__text {
          font-size: 14px;
          color: #86909c;
          span {
            color: #c9cdd4;
          }
        }
      }
    }
    .el-progress {
      width: 100%;
      &__text {
        margin-left: 20px;
      }
    }
  }
}
</style>
